﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using hlib.Code;
using SalesSys.Comm.Utility;
using SalesSys.DAL.Models;

namespace SalesSys.BLL.Depot
{
    public interface IDepotBLL
    {
        /// <summary>
        ///  商品库存数量
        /// </summary>
        /// <param name="providerId"></param>
        /// <param name="Ids">商品id</param>
        /// <returns></returns>
        DepotCommodity GoodsEnough(Guid providerId, Guid commodityId);

        /// <summary>
        /// 入库
        /// </summary>
        /// <param name="providerId"></param>
        /// <returns></returns>
        void Entry(WarehouseEntry warehouseEntry);

        /// <summary>
        /// 出库
        /// </summary>
        /// <param name="providerId"></param>
        /// <param name="isAllowOverrun">是否允许超出库存限制</param>
        /// <returns></returns>
        bool Delivery(DeliveryList deliveryList, bool isAllowOverrun=false);
        /// <summary>
        /// 采购入库
        /// </summary>
        /// <returns></returns>
        WarehouseEntry PurchasingEntry(PurchaseOrder purchase);
        /// <summary>
        /// 发货单出库
        /// </summary>
        /// <param name="deliverySheet"></param>
        /// <returns></returns>
        //bool DeliverGoods(DeliverySheet deliverySheet);

        
         
    }

    public class DepotBLL:IDepotBLL
    {
        private ProviderBLL providerBll=new ProviderBLL();
        private IBaseBLL<DepotRecord, Guid> depotRecordBll = new BaseBLL<DepotRecord, Guid>();
        IBaseBLL<DeliveryList, Guid> deliveryListBll = new BaseBLL<DeliveryList, Guid>();
        public DepotCommodity GoodsEnough(Guid providerId, Guid commodityId)
        {
            DepotCommodityBLL depotCommodityBLL = new DepotCommodityBLL();
            return depotCommodityBLL.GetDepotCommodity(providerId, commodityId);
        }

        public void Entry(WarehouseEntry warehouseEntry)
        {
            RuningEntry(warehouseEntry);
            
        }

        public IResultState OffsetWarehouseEntry(Guid id,IEmployee emp)
        {
            var dbll = new BaseBLL<WarehouseEntry, Guid>();
            var entry = dbll.Details(id);
            if (entry == null)
            {
                return ReState.ArgError.Create();
            }
            var offset = new WarehouseEntry();
            offset.From = WarehouseEntrySourcce.Offset;
            offset.FromId = entry.Id;
            offset.Provider = entry.Provider;
            offset.Creater = new EmployeeBLL().Details(emp.Id);
            var list = entry.StockGoods.Select(p => new StockGoods()
            {
                Commodity = p.Commodity,
                Count = -p.Count,
                DeliveryPrice = p.DeliveryPrice,
                IsIn = p.IsIn,
                NormPrice = p.NormPrice,
                Price = p.Price,
                TotalWeight = -p.TotalWeight,
                SourcePrice = p.SourcePrice,
                Weight = p.Weight
            }).ToArray();
            offset.StockGoods = list;
            entry.State = WarehouseEntryState.Offset;
            entry.Remark += string.Format("\n{0}[{1}]进行冲红操作", DateTime.Now, emp.Name);
            using (var tran = new TransactionScope())
            {
                dbll.Create(offset);
                dbll.Edit(entry);
                Entry(offset);
                tran.Complete();
                return ReState.Success.Create();
            }

        }

        /// <summary>
        /// 出库
        /// </summary>
        /// <param name="deliveryList"></param>
        /// <returns>成功返回true库存不足返回false,isAllowOverrun=true时始终为true,</returns>
        public bool Delivery(DeliveryList deliveryList, bool isAllowOverrun=false)
        {
            var provider = deliveryList.Provider;
            foreach (var goods in deliveryList.StockGoods)
            {
                var comd = provider.DepotCommoditys.FirstOrDefault(p => p.CommodityId == goods.Commodity.Id);
                var record = new DepotRecord();
                record.FromId =deliveryList.Id;
                record.Type =DepotRecord.RecordType.Send;
                provider.DepotRecords.Add(record);

                if (comd == null)
                {
                    throw new ArgumentException("不存在的仓库商品");
                }
                record.BeforeTotalCount = comd.Count;
                record.BeforeTotalWeight = comd.Amount;

                comd.Amount -= goods.TotalWeight;
                comd.Count -= goods.Count;

                record.Weight = goods.TotalWeight /goods.Count;
                record.TotalWeight = goods.TotalWeight;

                record.AfterTotalCount = comd.Count;
                record.AfterTotalWeight = comd.Amount;
                record.CommodityId = comd.CommodityId;
                //todo 先入先出，设置FromId
                provider.DepotRecords.Where(
                    p =>
                        p.Type == DepotRecord.RecordType.Into && p.CommodityId == comd.CommodityId &&
                        p.TotalWeight - p.SendedWeight > 0).OrderByDescending(p=>p.CreateTime);

                if (isAllowOverrun&&comd.Amount < comd.MinAmount)
                {
                    return false;
                }
                record.Commodity = comd.Commodity;
                record.Price = goods.Price;
                record.Count = goods.Count;
            }
           
            providerBll.Edit(provider);
            return true;
        }

        public void Select(Provider provider, Guid commodityId)
        {
            provider.DepotRecords.Where(
                  p =>
                      p.Type == DepotRecord.RecordType.Into && p.CommodityId == commodityId &&
                      p.TotalWeight - p.SendedWeight > 0).OrderByDescending(p => p.CreateTime);

        }

        private WarehouseEntry CreateEntry(PurchaseOrder purchase)
        {
            var entry = new WarehouseEntry();
            entry.StockGoods = new List<StockGoods>();
            foreach (var goods in purchase.Goodses)
            {
                var stGoods = new StockGoods();
                stGoods.Commodity = goods.Commodity;
                stGoods.Count = goods.Count;
                stGoods.DeliveryPrice = purchase.DeliveryPrice;
                stGoods.IsIn = true;
                stGoods.NormPrice = goods.NormPrice;
                stGoods.Price = goods.Price;
                stGoods.SourcePrice = goods.Price;
                stGoods.TotalWeight = goods.Weight;
                stGoods.Weight = goods.Weight/goods.Count;
                entry.StockGoods.Add(stGoods);
            }
            entry.Creater = purchase.Creater;
            entry.DeliveryPrice = purchase.DeliveryPriceTotal;
            entry.FromId = purchase.Id;
            entry.From = WarehouseEntrySourcce.Purchase;
            entry.Provider = purchase.ToDepot;
            new BaseBLL<WarehouseEntry, Guid>().Create(entry);
            return entry;
        }
        /// <summary>
        /// 执行一个入库单
        /// </summary>
        /// <param name="entry"></param>
        private void RuningEntry(WarehouseEntry entry)
        {
                var provider=providerBll.Details(entry.Provider.Id); 
        //  var deliveryP=  purchase.DeliveryPriceTotal/purchase.TotalWeight;
     
            foreach (var goods in entry.StockGoods)
            {
               var comd= provider.DepotCommoditys.FirstOrDefault(p => p.CommodityId == goods.Commodity.Id);
               var record = new DepotRecord();
                record.FromId =goods.Id;
                record.Type =DepotRecord.RecordType.Into;
                provider.DepotRecords .Add(record);
              
                if (comd==null)
                {
                    comd = new DepotCommodity();
                    comd.Amount = goods.TotalWeight;
                    comd.Count = goods.Count;
                    comd.CommodityId = goods.Commodity.Id;
                    comd.Provider = entry.Provider;
                    comd.UpdateTime = DateTime.Now;
                    //comd.Price = 0;// goods.Price;

                    record.BeforeTotalCount = 0;
                    record.BeforeTotalWeight = 0;
                    record.CommodityId = comd.CommodityId;
                    record.Price = goods.Price;
                    record.Weight = (goods.TotalWeight/goods.Count);
                    record.TotalWeight = goods.TotalWeight;
                    record.Count = goods.Count;

                    record.AfterTotalCount = comd.Count;
                    record.AfterTotalWeight = comd.Amount;

                    provider.DepotCommoditys.Add(comd);

                }
                else
                {
                    record.BeforeTotalCount=comd.Count;
                    record.BeforeTotalWeight = comd.Amount;
                    record.Price = goods.Price;
                    record.Weight =(goods.TotalWeight / goods.Count);
                    record.TotalWeight = goods.TotalWeight;
                    record.Count = goods.Count;

                    comd.Amount += goods.TotalWeight;
                    comd.Count += goods.Count;
                    record.AfterTotalCount = comd.Count;
                    record.AfterTotalWeight = comd.Amount;
                    record.CommodityId = comd.CommodityId;
                }
                record.Commodity = comd.Commodity;
       
            }
            providerBll.Edit(provider);


        }

        

        /// <summary>
        /// 采购入库
        /// </summary>
        /// <param name="purchase"></param>
        /// <returns></returns>
        /// <remarks>
        /// 生成入库单
        /// 依照入库单生成入库流水
        /// 判断仓库中是否有此商品
        /// 添加商品，数量、重量
        /// </remarks>
        public WarehouseEntry PurchasingEntry(PurchaseOrder purchase)
        {
            using (var tran = new TransactionScope())
            {
                var entrty = CreateEntry(purchase);
                purchase.State=PurchaseOrder.PurchaseState.EntryEnd;
                RuningEntry(entrty);
                tran.Complete();
                return entrty;
            }
        }

        /// <summary>
        /// 出库
        /// </summary>
        /// <param name="deliveryList"></param>
        /// <returns></returns>
        /// <remarks>
        /// Tran{
        /// 判断发货类型
        /// 如果为销售， 检查对应订单是否有锁货单，获取库存锁货
        /// 判断库存足够
        /// 执行出库减去库存
        /// 创建出库单
        /// 先进先出出库
        /// 释放锁库单
        /// 
        /// }
        /// </remarks>
        //public bool DeliverGoods(DeliverySheet deliveryList)
        //{

        //    throw new NotImplementedException();

        //}
    }
}
